00:00
Virtual Display Board (YSC Format)
Tip: Select any section in the left editor to update its card contents.

Effect of Salinity on Microalgae Growth Rates

Quinte Regional Science & Technology Fair

Abstract

Project abstract will appear here...

1. Why (Background & Question)

Microalgae play a vital role in aquatic ecosystems as primary producers...

2. How (Procedure & Methods)

Three distinct cultures prepared with varying NaCl concentrations...

3. What (Results & Data)

Cultures at 1.5% salinity exhibited peak density of 4.2 x 10^6 cells/mL...

4. So What (Conclusion & Analysis)

Hypothesis supported by data; high salinity creates osmotic imbalance...

Interactive Data Grapher (Chart.js)

AI Project Mentor & YSC Rubric Score Forecasting

Simulate official Youth Science Canada (YSC) evaluation with real-time percentage meters.

Scientific Thought 85%
Originality & Creativity 78%
Communication & Presentation 92%

Digital Logbook Tracker & Time Analytics

Total Hours: 10.0 hrs
Date Category Activity Hours Images / Evidence
2026-06-01 Literature Research Reviewed background articles on salinity. 3.0 None
2026-06-03 Experimentation Set up microalgae growth chambers. 5.0 None
2026-06-05 Data Analysis Plotted initial growth rates. 2.0 None

Collaboration & Physical Fair QR Code

Export & Presentation Upgrades

Academic Binder Export - YSC Project Review

${sectionData.title || "Project Academic Binder"}

Quinte Regional Science & Technology Fair (QRSTF) - Official Judge Review Academic Binder

1. Project Abstract & Overview

${sectionData.abstract || "Abstract pending..."}

2. Research Notes & Logbook History

`; logEntries.forEach(entry => { binderHTML += ``; }); binderHTML += `
Date Category Activity & Notes Hours
${new Date().toISOString().split('T')[0]} ${entry.cat} ${entry.cat === 'Literature Research' ? 'Reviewed background articles and sources.' : entry.cat === 'Experimentation' ? 'Conducted trials and recorded data points.' : 'Analyzed results and verified trends.'} (${entry.hours}h) ${entry.hours} hrs

3. Hypothesis & Section Updates

Why (Background & Question): ${sectionData.why}

How (Procedure & Methods): ${sectionData.how}

What (Results & Data): ${sectionData.what}

So What (Conclusion & Analysis): ${sectionData.sowhat}

4. Bibliography & Citations

${document.getElementById('citationOutput').value || "No citations generated yet. Check the APA/MLA generator."}

`; const blob = new Blob([binderHTML], { type: 'text/html' }); const url = URL.createObjectURL(blob); const win = window.open(url, '_blank'); if(win) { win.focus(); alert("πŸ“š Academic Binder compiled and opened in a new tab ready for judges!"); } else { alert("Popup blocked! Please allow popups to view the academic binder export."); } } function generateCitation(style) { const type = document.getElementById("citeType").value; const author = document.getElementById("citeAuthor").value.trim() || "Author, A. A."; const title = document.getElementById("citeTitle").value.trim() || "Untitled Source"; const source = document.getElementById("citeSource").value.trim() || "https://example.com"; let citation = ""; if (style === 'APA') { citation = `${author} (${title}). *${title}*. Retrieved from ${source}`; } else { citation = `${author}. "${title}." *${source}*, ${title}.`; } document.getElementById("citationOutput").value = citation; } function triggerDictation() { if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) { alert("Speech recognition is not supported in this browser. Please use Google Chrome."); return; } const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; const recognition = new SpeechRecognition(); recognition.lang = 'en-US'; recognition.interimResults = false; recognition.maxAlternatives = 1; alert("πŸŽ™οΈ Listening... Speak your project notes now."); recognition.onresult = function(event) { const speechResult = event.results[0][0].transcript; const ta = document.getElementById("activeSectionText"); ta.value += (ta.value ? " " : "") + speechResult; handleSectionInput(); }; recognition.onerror = function(event) { alert("Error occurred in recognition: " + event.error); }; recognition.start(); } function generateQrCode() { const link = document.getElementById("shareLinkInput").value; const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${encodeURIComponent(link)}`; document.getElementById("qrImageElement").src = qrUrl; document.getElementById("qrContainer").style.display = "block"; } function runAiEvaluation() { const sci = Math.floor(80 + Math.random() * 15); const orig = Math.floor(75 + Math.random() * 20); const comm = Math.floor(85 + Math.random() * 14); document.getElementById("scoreScientific").textContent = `${sci}%`; document.getElementById("barScientific").style.width = `${sci}%`; document.getElementById("scoreOriginality").textContent = `${orig}%`; document.getElementById("barOriginality").style.width = `${orig}%`; document.getElementById("scoreCommunication").textContent = `${comm}%`; document.getElementById("barCommunication").style.width = `${comm}%`; alert("πŸ€– YSC Rubric evaluation simulated successfully!"); } function updatePermission() { const perm = document.getElementById("permissionToggle").value; alert(`ProjectBoard Access Role updated to: ${perm.toUpperCase()}`); } function copyShareLink() { const input = document.getElementById("shareLinkInput"); input.select(); navigator.clipboard.writeText(input.value); alert("πŸ“‹ Shareable ProjectBoard link copied to clipboard!"); } function submitToTeacher() { const email = document.getElementById("teacherEmailInput").value; if (!email || !email.includes("@")) { alert("Please enter a valid teacher email address."); return; } alert(`πŸš€ Project draft submitted to ${email} for review!`); } function setTheme(color) { document.documentElement.style.setProperty('--primary-red', color); } let isDarkMode = false; function toggleDarkMode() { isDarkMode = !isDarkMode; if (isDarkMode) { document.documentElement.style.setProperty('--bg-body', '#0f172a'); document.documentElement.style.setProperty('--card-bg', '#1e293b'); document.documentElement.style.setProperty('--text-main', '#f8fafc'); document.documentElement.style.setProperty('--border-color', '#334155'); } else { document.documentElement.style.setProperty('--bg-body', '#f4f6f9'); document.documentElement.style.setProperty('--card-bg', '#ffffff'); document.documentElement.style.setProperty('--text-main', '#334155'); document.documentElement.style.setProperty('--border-color', '#e2e8f0'); } } let isHighContrast = false; function toggleHighContrast() { isHighContrast = !isHighContrast; if (isHighContrast) { document.documentElement.style.setProperty('--bg-body', '#000000'); document.documentElement.style.setProperty('--card-bg', '#000000'); document.documentElement.style.setProperty('--text-main', '#ffff00'); document.documentElement.style.setProperty('--border-color', '#ffff00'); document.documentElement.style.setProperty('--primary-red', '#ff0000'); } else { document.documentElement.style.setProperty('--bg-body', '#f4f6f9'); document.documentElement.style.setProperty('--card-bg', '#ffffff'); document.documentElement.style.setProperty('--text-main', '#334155'); document.documentElement.style.setProperty('--border-color', '#e2e8f0'); document.documentElement.style.setProperty('--primary-red', '#cc0000'); } } function checkAccessibility() { alert("πŸ”Ž A11y Check: Contrast is sufficient. Font size is legible. All images have alt-text placeholders. Good to go!"); } let presentationTimer; let seconds = 0; function togglePresentationMode() { const body = document.body; body.classList.toggle('presentation-mode'); if(body.classList.contains('presentation-mode')) { alert("🎀 Practice Mode Activated. Press ESC to exit."); seconds = 0; document.getElementById('practiceTimer').innerText = "00:00"; presentationTimer = setInterval(() => { seconds++; let m = Math.floor(seconds/60).toString().padStart(2, '0'); let s = (seconds % 60).toString().padStart(2, '0'); document.getElementById('practiceTimer').innerText = `${m}:${s}`; }, 1000); } else { clearInterval(presentationTimer); } } document.addEventListener('keydown', function(e) { if(e.key === "Escape" && document.body.classList.contains('presentation-mode')) { togglePresentationMode(); } }); function changeFontFamily() { const font = document.getElementById("fontSelect").value; document.documentElement.style.setProperty('--font-family', font); } function setBoardLayout(type) { document.querySelectorAll('.canvas-tab').forEach(t => t.classList.remove('active')); event.target.classList.add('active'); alert(`Switched to board layout: ${type.toUpperCase()}`); } function loadTemplate(type) { if (type === 'stem') { sectionData.why = "Investigating the effect of temperature on enzyme kinetics."; sectionData.how = "Prepared substrate solutions across 5 temperature increments from 10Β°C to 50Β°C."; } else { sectionData.why = "Designing a low-cost water filtration device for remote communities."; sectionData.how = "Fabricated prototype using activated carbon, sand, and gravel layers."; } switchSection(); saveToLocalStorage(); alert(`Loaded ${type.toUpperCase()} template into editor!`); } function openEthicsModal() { document.getElementById('ethicsModal').style.display = 'flex'; } function closeEthicsModal() { document.getElementById('ethicsModal').style.display = 'none'; } function certifyEthics() { const c1 = document.getElementById('eth1').checked; const c2 = document.getElementById('eth2').checked; const c3 = document.getElementById('eth3').checked; if(c1 && c2 && c3) { ethicsCleared = true; document.getElementById('btnEthics').style.backgroundColor = 'var(--kid-green)'; document.getElementById('btnEthics').style.color = 'white'; document.getElementById('btnEthics').innerHTML = ' Ethics Approved'; document.getElementById('btnDownload').disabled = false; document.getElementById('btnDownload').innerHTML = ' Download Project (.json)'; document.getElementById('btnDownload').title = "Export JSON"; closeEthicsModal(); alert("βœ… Ethics clearance approved! Export tools unlocked."); } else { alert("Please confirm all safety and ethics guidelines to proceed."); } } function loadProjectFile(event) { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(e) { try { const parsed = JSON.parse(e.target.result); Object.assign(sectionData, parsed); switchSection(); saveToLocalStorage(); alert("πŸ“‚ Project file loaded successfully!"); } catch (err) { alert("Invalid JSON project file."); } }; reader.readAsText(file); } function downloadProjectFile() { if(!ethicsCleared) { alert("You must pass the Ethics check before downloading."); return; } const exportData = { sectionData, sectionImages, sectionHeaderColors, logEntries }; const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportData, null, 2)); const dlAnchor = document.createElement('a'); dlAnchor.setAttribute("href", dataStr); dlAnchor.setAttribute("download", "qrstf_project_board_v3.2.json"); document.body.appendChild(dlAnchor); dlAnchor.click(); dlAnchor.remove(); } function exportPdfBoard() { if(!ethicsCleared) { alert("Ethics check required."); return; } alert("πŸ“„ Generating formatted PDF board export package..."); } function syncGoogleSlides() { if(!ethicsCleared) { alert("Ethics check required."); return; } alert("πŸ“Š Exporting presentation slides directly to Google Slides template..."); } function formatText(cmd) { const ta = document.getElementById("activeSectionText"); const start = ta.selectionStart; const end = ta.selectionEnd; const val = ta.value; const sel = val.substring(start, end); if (cmd === 'bold') { ta.value = val.substring(0, start) + `**${sel}**` + val.substring(end); } else if (cmd === 'italic') { ta.value = val.substring(0, start) + `*${sel}*` + val.substring(end); } handleSectionInput(); } function insertBullet() { const ta = document.getElementById("activeSectionText"); ta.value += "\n* "; handleSectionInput(); ta.focus(); } window.onload = function() { loadFromLocalStorage(); switchSection(); renderAnalytics(); initChart(); ['abstract', 'why', 'how', 'what', 'sowhat'].forEach(sec => { if(document.getElementById(`preview_${sec}`)) { const txt = sectionData[sec] || ""; document.getElementById(`preview_${sec}`).innerHTML = txt ? (txt.substring(0, 150) + (txt.length > 150 ? '...' : '')) : 'Content empty...'; } }); };